package com.me.seckill.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * RabbitMQ 配置类
 *
 * @author ME
 * @date 2021/7/9
 */
@Configuration
public class RabbitMQConfig {

    /** Topic 交换机名称 */
    public static final String SECKILL_TOPIC_EXCHANGE = "seckill-exchange";
    /** Fanout 交换机名称 */
    public static final String FANOUT_EXCHANGE = "fanout-exchange";
    /** Headers 交换机名称 */
    public static final String HEADERS_EXCHANGE = "headers-exchange";

    /** 队列名称 */
    public static final String SECKILL_QUEUE = "seckill-queue";

    /** 路由键 */
    public static final String ROUTING_KEY = "seckill.#";

    /**
     * 配置 amqpTemplate 消息转换器：将消息转换为JSON格式
     */
    @Bean
    public MessageConverter getMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    /** 声明交换机 */
    @Bean(SECKILL_TOPIC_EXCHANGE)
    public Exchange seckillExchange(){
        return ExchangeBuilder.topicExchange(SECKILL_TOPIC_EXCHANGE)
                // .durable(true) // 默认 true
                .build();
    }

    /** 定义一个消息队列 */
    @Bean(SECKILL_QUEUE)
    public Queue seckillQueue() {
        return new Queue(SECKILL_QUEUE);
    }

    /** 将队列与 Topic交换机 进行绑定，并指定路由键 */
    @Bean("seckillBinding")
    public Binding topicBinding(@Qualifier(SECKILL_QUEUE) Queue queue,
                                @Qualifier(SECKILL_TOPIC_EXCHANGE) Exchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY).noargs();
    }

    /** 声明 fanout 交换机 */
    @Bean
    FanoutExchange fanoutExchange() {
        return new FanoutExchange(FANOUT_EXCHANGE);
    }

    /** 将队列与 fanout 交换机进行绑定 */
    @Bean
    Binding fanoutBinding(Queue queue, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }

    /** 声明 Headers 交换机 */
    @Bean
    HeadersExchange headersExchange() {
        return new HeadersExchange(HEADERS_EXCHANGE);
    }

    /** 将队列与 headers交换机 进行绑定 */
    @Bean
    Binding headersBinding(Queue queue, HeadersExchange headersExchange) {
        Map<String, Object> map = new HashMap<>();
        map.put("First", "A");
        map.put("Fourth", "D");
        // whereAny表示部分匹配，whereAll表示全部匹配
        return BindingBuilder.bind(queue).to(headersExchange)
                .whereAny(map)
                // .whereAll(map)
                .match();
    }

}
